#ifndef LOGGER_H__
#define LOGGER_H__

#include <windows.h>
#include <string.h>

#include "def.h"

#pragma warning( disable:4042 )
#include <typeinfo.h>

#ifdef Redundency
#include <string>
#include <map>
#endif
template <long Id,long Data>
class QueryAble
{
public:
	QueryAble() { m_lData = Data; }
	virtual long getId(){ return Id; }
	virtual long getData() { return m_lData;}
private:

	long m_lData;

};

class NullClass : public QueryAble<QUERY_ID_NULL,-1>
{
};

template <long Level = LOG_LEVEL_NORMAL>
class LogLevel  : public QueryAble<QUERY_ID_LOGLEVEL,Level>
{
};

template <long Type = LOG_TYPE_NOTIFICATION>
class LineType  : public QueryAble<QUERY_ID_LINETYPE,Type>
{
};

template <long Id = KEYID_NULL>
class KeyId  : public QueryAble<QUERY_ID_KEYID,Id>
{
};

template <long Id = CONSOLEID_NULL>
class ConsoleId  : public QueryAble<QUERY_ID_CONSOLEID,Id>
{
};

template <class _ARG1 = LogLevel<>,class _ARG2 = LineType<>,class _A3 = KeyId<>,class _A4 = ConsoleId<>>
class sLogMsgf
{
public:
	sLogMsgf(LPCSTR strFormat,...)
	{

		//if (_LOGGER.GetLogLevel() >= lLogLevel)
		{
			_ARG1 cLogLevel;
			_ARG2 cLineType;
			_A3 cKeyId;
			_A4 cConsoleId;

			char sTmpMsg[10240] = {0};
			va_list marker;
			va_start(marker,strFormat);
			
			strcat_s(sTmpMsg,sizeof(sTmpMsg),strFormat);
			vsprintf_s(sTmpMsg,sizeof(sTmpMsg),strFormat,marker);
#ifdef Redundency
			
			long Key = cKeyId.getData();
			
			if ( Key != -1)
			{
				static	std::map<long,std::string>	allKeys;
				std::string	val = sTmpMsg;	
				
				if (allKeys[Key] == val)
				{
					//
				}
				else
				{
					strcat_s(sTmpMsg,sizeof(sTmpMsg),"\n");
					printf(sTmpMsg);
					allKeys[Key] = val;
				}
			
			}
			else
			{
				strcat_s(sTmpMsg,sizeof(sTmpMsg),"\n");
				printf(sTmpMsg);
			}			
#else
			strcat_s(sTmpMsg,sizeof(sTmpMsg),"\n");
			printf(sTmpMsg);
#endif
		}
			
	}
};


#endif